//
//  BBMVCController.m
//  BattleFrontierV3
//
//  Created by Eric on 12/23/11.
//  Copyright (c) 2011 __MyCompanyName__. All rights reserved.
//

#import "BBMVC.h"
#import "BBUtil.h"

/*--------Request----------*/
@implementation BBMVCRequest
@synthesize param, callbackTgt, callbackMethod, reqMethod;
-(void)dealloc{
    self.param = nil;
    self.callbackTgt = nil;
    [super dealloc];
}

@end



/*--------Action----------*/
@implementation BBMVCAction
#ifdef __IPHONE_OS_VERSION_MAX_ALLOWED
-(void)shareContext{
    EAGLContext *k_context = [[[EAGLContext alloc]
                               initWithAPI :kEAGLRenderingAPIOpenGLES1
                               sharegroup:[[[[CCDirector sharedDirector] openGLView] context] sharegroup]] autorelease];
    [EAGLContext setCurrentContext:k_context];
}
#elif defined(__MAC_OS_X_VERSION_MAX_ALLOWED)
-(void)shareContext{
}
#endif 

-(id)doTask:(BBMVCRequest*)request{
    id result = nil;
    if (request.reqMethod) {
        result = [self performSelector:request.reqMethod withObject:request.param];
    }
    return result;    
}

-(void)doTaskAsyn:(BBMVCRequest*)request{
    [self shareContext];
    id result = [self doTask:request];
    [request.callbackTgt performSelector:request.callbackMethod withObject:result];
    
}


-(id)doAction:(id)param{
    NSLog(@"BBMVCAction:doAction");
    return nil;
}
@end



/*--------Dispather----------*/
@implementation BBMVCDispatcher
static BBMVCDispatcher* s_dispatcher;

-(void)dealloc{
    [_actions release];
    [_rules release];
    [_opQueue release];
    [super dealloc];
}


+(BBMVCDispatcher*)dispatcher{
    if (s_dispatcher==nil) {
		s_dispatcher = [[[self class] alloc] init];
        [s_dispatcher initDispatcher:MVC_PLIST_FILE];
	}
	return s_dispatcher;
}

-(void)initDispatcher:(NSString*)configFile{
    NSString *path = [[NSBundle mainBundle] pathForResource:configFile ofType:@"plist"];
    NSDictionary* config = [NSDictionary dictionaryWithContentsOfFile:path];
    
    NSDictionary* actionsTmp = [config objectForKey:@"actions"];
    NSMutableDictionary* actions = [[NSMutableDictionary alloc] initWithDictionary:actionsTmp];
    for (NSString* actionName in actions) {
        NSDictionary* actionAttr= [actionsTmp objectForKey:actionName];
        BOOL single = [actionAttr boolValue:@"single" defaultVal:YES];
        if (single) {
            NSString* className = [actionAttr objectForKey:@"class"];
            Class class = NSClassFromString(className);
            if ([class isSubclassOfClass:[BBMVCAction class]]) {
                BBMVCAction* action = [[[class alloc] init] autorelease];
                NSMutableDictionary* actionAttrTmp = [NSMutableDictionary dictionaryWithDictionary:actionAttr];
                [actionAttrTmp setObject:action forKey:@"instance"];
                [actions setObject:actionAttrTmp forKey:actionName];
            }
        }
    }
    
    NSDictionary* rulesTmp = [config objectForKey:@"rules"];
    
    _actions = actions;
    _rules = [[NSMutableDictionary alloc] initWithDictionary:rulesTmp];
    _opQueue = [[NSOperationQueue alloc] init];
}
-(BBMVCAction*)getAction:(NSString*)request rule:(NSDictionary*)rule{
    BBMVCAction* action = nil;
    NSString* actionClassName = nil;
    
    NSString* actionName = [rule objectForKey:@"action"];
    if (actionName) {
        NSDictionary* actionAttr = [_actions objectForKey:actionName];
        action = [actionAttr objectForKey:@"instance"];
        if (!action) {
            actionClassName = [actionAttr objectForKey:@"class"];
        }
    }else{
        actionClassName = [rule objectForKey:@"class"];
    }
    if (!action && actionClassName) {
        Class class = NSClassFromString(actionClassName);
        if ([class isSubclassOfClass:[BBMVCAction class]]) {
            action = [[[class alloc] init] autorelease];
        }
    }
    return action;
}
-(id)request:(NSString*)request param:(id)param{
    NSDictionary* rule = [_rules objectForKey:request];
    BBMVCAction* action = [self getAction:request rule:rule];
    if (action) {
        NSString* reqMethodName = [rule value:@"method" defaultVal:@"doAction:"];
        SEL reqMethod = NSSelectorFromString(reqMethodName);
        BBMVCRequest* request = [[[BBMVCRequest alloc] init] autorelease];
        request.param = param;
        request.reqMethod = reqMethod;
        return [action doTask:request];
    }    
    return nil;
}
-(id)request:(NSString*)request{
    return [self request:request param:nil];
}

-(void)requestAsyn:(NSString*)request param:(id)param callbackTgt:(id)tgt callback:(SEL)method{
    NSDictionary* rule = [_rules objectForKey:request];
    BBMVCAction* action = [self getAction:request rule:rule];
    if (action) {
        NSString* reqMethodName = [rule value:@"method" defaultVal:@"doAction:"];
        SEL reqMethod = NSSelectorFromString(reqMethodName);
        BBMVCRequest* request = [[[BBMVCRequest alloc] init] autorelease];
        request.param = param;
        request.callbackTgt = tgt;
        request.callbackMethod = method;
        request.reqMethod = reqMethod;
        NSInvocationOperation *op = [[[NSInvocationOperation alloc] initWithTarget:action selector:@selector(doTask:) object:request] autorelease];
        [_opQueue addOperation:op];
    }    
}

@end
